<?php
require_once 'ZLib/File.php';
require_once 'ZLib/Exceptions/FileException.php';

/**
 * @license GPL v.3
 * @author Andrei Ermicioi (andrei.ermicioi@gmail.com)
 */
class ZLib_File_GDImage extends ZLib_File {
	
	protected $resource = NULL;
	private $type = NULL;
	
	public function __construct($filename) {
		parent::__construct($filename);
		
		if (!$this->isFile()) {
			throw new ZLib_Exceptions_FileException('Is not an image');
		}
		
		$this->type = exif_imagetype($this->getAbsolutePath());
		
		switch ($this->type) {
			case IMAGETYPE_GIF:
				$this->resource = imagecreatefromgif($this->getAbsolutePath());
				break;
			
			case IMAGETYPE_JPEG:
				$this->resource = imagecreatefromjpeg($this->getAbsolutePath());
				break;
			
			case IMAGETYPE_PNG:
				$this->resource = imagecreatefrompng($this->getAbsolutePath());
				break;
			
			default:
				throw new ZLib_Exceptions_FileException('Unsupported image format');
		}
	}
	
	public function getWidth() {
		return (int) imagesx($this->resource);
	}
	
	public function getHeight() {
		return (int) imagesy($this->resource);
	}
	
	public function getColorAtPos($x, $y) {
		return (int) imagecolorat($this->resource, $x, $y);
	}
	
	public function setTransparency($color) {
		imagecolortransparent($this->resource, $color);
	}
	
	public function resize($width, $height) {
		$image_resized = imagecreatetruecolor($width, $height);
		imagecopyresampled($image_resized, $this->resource, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
		$this->resource = $image_resized;
	}
	
	public function resizeByWidth($width) {
		$this->resize($width, $this->getHeight());
	}

	public function resizeByHeight($height) {
		$this->resize($this->getWidth(), $height);
	}
	
	public function scaleByWidth($width) {
		$this->resize($width, $this->getHeight() * $width / $this->getWidth());
	}

	public function scaleByHeight($height) {
		$this->resize($this->getWidth() * $height / $this->getHeight(), $height);
	}

	public function scaleByMax($size) {
		if ($this->getWidth() > $this->getHeight()) {
			$this->scaleByWidth($size);
		} else {
			$this->scaleByHeight($size);
		}
	}

	public function scaleByMin($size) {
		if ($this->getWidth() < $this->getHeight()) {
			$this->scaleByWidth($size);
		} else {
			$this->scaleByHeight($size);
		}
	}
	
	public function merge($image, $destX = 0, $destY = 0, $srcX = 0, $srcY = 0, $srcW = null, $srcH = null, $quality = 100) {
		if ($srcW == null) {
			$srcW = $image->getWidth();
		}

		if ($srcH == null) {
			$srcH = $image->getHeight();
		}

		imagecopymerge($this->resource, $image->resource, $destX, $destY, $srcX, $srcY, $srcW, $srcH, $quality);
	}
	
	public function dump($filename = null) {
		$result = false;
		$isnew = true;

		if ($filename == null) {
			$filename = $this->name;
			$isnew = false;
		}

		switch ($this->type) {
			case IMAGETYPE_GIF:
				$result = imagegif($this->resource, $filename);
				break;

			case IMAGETYPE_JPEG:
				$result = imagejpeg($this->resource, $filename);
				break;

			case IMAGETYPE_PNG:
				$result = imagepng($this->resource, $filename);
				break;
		}

		if (!$result) {
			throw new ZLib_Exceptions_FileException('Cannot save image');
		}

		return ($isnew) ? new ZLib_File_GDImage($filename) : $this;
	}
}
